<script>
  /* function Person(name, age) {
  // this => s1
  this.name = name
  this.age = age
  this.say = function () {
  console.log('Hello World')
  }
  }
  // !#1 构造函数继承/Call 式继承
  function Star(name, age) {
  // this => s1
  Person.call(this, name, age)
  }

  const s1 = new Star('尼古拉斯.赵四', 18)
  console.log(s1.name)
  console.log(s1.age)
  s1.say() */

  /* function Person(name, age) {
  // this => s1
  // this => s2
  this.name = name
  this.age = age
  this.say = function () {
  console.log('Hello World')
  }
  }
  function Star(name, age) {
  // this => s1
  // this => s2
  Person.call(this, name, age)
  }

  const s1 = new Star('尼古拉斯.赵四', 18)
  const s2 = new Star('尼古拉斯.赵六', 19)
  // !#2 构造函数继承的问题，明明干的事是一样，方法却不等，浪费内存空间
  console.log(s1.say === s2.say) // false */

  /* function Person(name, age) {
  this.name = name
  this.age = age
  }

  // !#3 构造函数继承的问题，期望挂到父类的原型上，但是构造函数继承搞不定
  Person.prototype.say = function () {
  console.log('Hello World')
  }

  function Star(name, age) {
  Person.call(this, name, age)
  }

  const s1 = new Star('尼古拉斯.赵四', 18)
  s1.say() */

  /* function Person(name, age) {
  this.name = name
  this.age = age
  }

  Person.prototype.say = function () {
  console.log('Hello World')
  }

  function Star(name, age) {
  Person.call(this, name, age)
  }
  Star.prototype = Person.prototype
  // !#4 相互影响，明明给儿子挂的方法
  Star.prototype.play = function () {
  console.log('play')
  }
  // 却影响到父亲了
  const p1 = new Person()
  p1.play() */

  /* function Person(name, age) {
  this.name = name
  this.age = age
  }

  Person.prototype.say = function () {
  console.log('Hello World')
  }

  function Star(name, age) {
  Person.call(this, name, age)
  }
  // p 是 Person 的实例，我说 Person 有的 p 都有，所以 p 有 name、age、say
  const p = new Person()
  // !#5 这儿确实会影响 p 实例，但是没关系，p 实例仅仅是用来继承的，没人用，只要不影响后续通过 new Person 创建的新实例就 ok
  Star.prototype = p
  Star.prototype.play = function () {
  console.log('play')
  }

  const s1 = new Star('尼古拉斯1', 18)
  const s2 = new Star('尼古拉斯2', 18)
  console.log(s1.say === s2.say)

  const ppp = new Person()
  ppp.play() */

  /* function Person(name, age) {
  this.name = name
  this.age = age
  }

  Person.prototype.say = function () {
  console.log('Hello World')
  }

  function Star(name, age) {
  Person.call(this, name, age)
  }
  const p = new Person()
  Star.prototype = p

  const s1 = new Star('尼古拉斯1', 18)
  // !#6 问题
  console.log(Star.prototype.construcor === Star)
  console.log(s1.__proto__.construcor === Star)
  console.log(s1.construcor === Star) // false */

  /* function Person(name, age) {
  this.name = name
  this.age = age
  }

  Person.prototype.say = function () {
  console.log('Hello World')
  }

  function Star(name, age) {
  Person.call(this, name, age)
  }
  // 原型继承
  Star.prototype = new Person()
  Star.prototype.construcor = Star

  const s1 = new Star('尼古拉斯1', 18)
  // !#6 问题
  console.log(Star.prototype.construcor === Star)
  console.log(s1.__proto__.construcor === Star)
  console.log(s1.construcor === Star) // false
  // 构造函数继承（继承的是属性）+原型继承（继承的父类原型上的方法） = 组合继承 */
  /* function Person(name, age) {
    this.name = name
    this.age = age
  }

  Person.prototype.say = function () {
    console.log('Hello World')
  }

  function Star(name, age) {
    Person.call(this, name, age)
  }
  // !#7 把属性 undefined 给了 Start.prototype，没必要
  Star.prototype = new Person()
  Star.prototype.construcor = Star

  const s1 = new Star('尼古拉斯1', 18) */


  /* function Person(name, age) {
    this.name = name
    this.age = age
  }

  Person.prototype.say = function () {
    console.log('Hello World')
  }

  function Star(name, age) {
    Person.call(this, name, age)
  }

  // 寄生继承，把 Person.prototype 上面的方法寄生给了 Temp.prototype
  function Temp() { }
  // 把 Person.prototype 上面的有的都给了 Temp.prototype
  Temp.prototype = Person.prototype
  const t = new Temp()

  // t 只有 say
  Star.prototype = t
  Star.prototype.construcor = Star

  const s1 = new Star('尼古拉斯1', 18)

  console.log(s1) */

  /* function Person(name, age) {
    this.name = name
    this.age = age
  }

  Person.prototype.say = function () {
    console.log('Hello World')
  }

  function Star(name, age) {
    Person.call(this, name, age)
  }


  // 寄生继承
  function create(Person) {
    function Temp() { }
    Temp.prototype = Person.prototype
    return new Temp()
  }

  // t 只有 say
  Star.prototype = create(Person)
  Star.prototype.construcor = Star

  const s1 = new Star('尼古拉斯1', 18)

  console.log(s1) */


  function Person(name, age) {
    this.name = name
    this.age = age
  }

  Person.prototype.say = function () {
    console.log('Hello World')
  }

  function Star(name, age) {
    Person.call(this, name, age)
  }


  // 寄生继承
  function create(Person, Star) {
    function Temp() {
      // 实例 => t => Star.prototype
      this.construcor = Star
    }
    Temp.prototype = Person.prototype
    return new Temp()
  }

  // t 只有 say
  Star.prototype = create(Person, Star) // create 拿到的结果是 Temp 的实例
  // Star.prototype.construcor = Star

  const s1 = new Star('尼古拉斯1', 18)

  console.log(s1)


  // 1. 构造函数继承 => 继承的是属性
  // 2. 原型继承 => 继承的是父类构造函数上的方法
  // 3. 组合继承 = 构造函数继承 + 原型继承
  // 4. 原型继承的问题：子类的.prototype 上有无用属性是 undefined
  // 5. 寄生继承，弄一个新方法，把父类.prototype 等于新方法.prototype，然后把新方法的实例给了子类.prototype
  // 6. 寄生组合继承 => 构造函数继承 + 寄生继承
</script>